﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DiscoveryLogic.UI.Layouts.Controls
{
    /// <summary>
    /// RadialItemPanel is used by RadialItemControl to correctly position the Image and Label at the correct location
    /// based on the control's attached RadialPanel.Angle property.
    /// </summary>
    public class RadialItemPanel : Panel
    {
        #region Constructors

        public RadialItemPanel()
        {
            // Note - if the panel doesn't have a background property, it won't come up in the HitTest() used by
            // the RadialPanel object, hence the reason why we assert its background to transparent here.
            Background = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));
        }

        #endregion // Constructors

        #region Member Functions

        protected override Size MeasureOverride(Size availableSize)
        {
            RadialItemControl parent = Parent as RadialItemControl;

            if (parent != null)
            {
                // We always want our panel to match the size of the RadialItemControl we're contained within
                // and if we're not, we should just use the default behaviour. We can't set the Width and Height
                // of the panel anywhere else (AFAIK), so instead we just grab it here.
                availableSize.Width = parent.Width;
                availableSize.Height = parent.Height;
                return availableSize;
            }
            return base.MeasureOverride(availableSize);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {            
            // Check that our parent object is a RadialItemControl before we begin
            RadialItemControl parent = Parent as RadialItemControl;

            if (parent == null)
                return finalSize;

            FrameworkElement imageElement = parent.Image;
            FrameworkElement labelElement = parent.Label;
            Point radius = (Point) parent.GetValue(RadialItemControl.RadiusProperty);//parent.Radius;
            double angle = (double) parent.GetValue(RadialPanel.AngleProperty);
            double radians = angle*(Math.PI/180);

            // Position the elements of this panel such that the image element is always centred, and the label element
            // is always positioned at the angle related to the item on the RingPanel control (an attached property).
            // We use the "Radius" property to define how far away from the center of this item the text is positioned.

            double centerX = finalSize.Width / 2;
            double centerY = finalSize.Height / 2;            

            // Ensure we only try and reposition the item if we have some content for that, otherwise we'll get an exception
            if (imageElement != null)
            {
                double imageX = 0, imageY = 0, imageW = 0, imageH = 0;

                imageW = imageElement.Width;
                imageH = imageElement.Height;
                imageX = centerX - imageW / 2;
                imageY = centerY - imageH / 2;
                imageElement.Arrange(new Rect(imageX, imageY, imageW, imageH));
            }
            if (labelElement != null)
            {
                double textX = 0, textY = 0, textW = 0, textH = 0;

                textW = (labelElement.Width > 0) ? labelElement.Width : labelElement.ActualWidth;
                textH = (labelElement.Height > 0) ? labelElement.Height : labelElement.ActualHeight;
                textX = (centerX + (Math.Cos(radians) * radius.X));
                textY = (centerY + (Math.Sin(radians) * radius.Y));
                // Align to right of text, if we're on the left side of the circle
                if (angle > 90 && angle < 270)
                    textX -= textW;
                // Align to bottom of text, if we're on the upper side of the circle
                if (angle > 180)
                    textY -= textH;
                labelElement.Arrange(new Rect(textX, textY, textW, textH));
            }
            return base.ArrangeOverride(finalSize);
        }

        #endregion // Member Functions
    }
}
